﻿using System;
using System.Windows.Forms;
using System.Web.Security;

namespace AspUserManager
{
	public partial class MainForm : Form
	{
		public MainForm()
		{
			InitializeComponent();
		}

		private void MainForm_Load(object sender, EventArgs e)
		{
			// make sure menu texts are correct
			tabControl_SelectedIndexChanged(this, EventArgs.Empty);

			Application.Idle += Delayed_Load;
			Application.Idle += Application_Idle;
		}

		void Application_Idle(object sender, EventArgs e)
		{
			if (tabControl.SelectedTab == tabUsers) {
				bool hasUserSelected = listUsers.SelectedItems.Count > 0;
				menuEditDelete.Enabled = hasUserSelected;
				menuEditUser.Enabled = hasUserSelected;

				if (hasUserSelected) {
					MembershipUser user = (MembershipUser)listUsers.FocusedItem.Tag;
					menuActionsUnlock.Enabled = user.IsLockedOut;
				} else
					menuActionsUnlock.Enabled = false;
			} else {
				bool hasRoleSelected = listRoles.SelectedIndex >= 0;
				menuEditDelete.Enabled = hasRoleSelected;
				menuEditUser.Enabled = false;
				menuActionsUnlock.Enabled = false;
			}
			toolDelete.Enabled = menuEditDelete.Enabled;
			menuCtxDeleteUser.Enabled = menuEditDelete.Enabled;
			menuCtxUnlockUser.Enabled = menuActionsUnlock.Enabled;
		}

		// this is called when the application first starts
		private void Delayed_Load(object sender, EventArgs e)
		{
			Application.Idle -= Delayed_Load;

			menuEditRefresh_Click(this, EventArgs.Empty);
		}

		private void menuEditRefresh_Click(object sender, EventArgs e)
		{
			Cursor oldCursor = Cursor.Current;
			try {
				Cursor.Current = Cursors.WaitCursor;
				foreach (MembershipUser user in Membership.GetAllUsers()) {
					listUsers.Items.Add(user.UserName);
				}
				ListUsersRefresh(0);
				ListRolesRefresh();
			} catch (Exception ex) {
				MessageBox.Show("The ASP Database could not be reached. Make sure " +
					"the entries in the '<system.web>' settings in the application " +
					"config file are correct.\n\n" + ex.Message, Application.ProductName);
			} finally {
				Cursor.Current = oldCursor;
			}
		}

		private void menuEditInsert_Click(object sender, EventArgs e)
		{
			if (tabControl.SelectedTab == tabUsers)
				ListUsersInsert(sender, e);
			else
				ListRolesInsert(sender, e);
		}


		private void menuEditDelete_Click(object sender, EventArgs e)
		{
			if (tabControl.SelectedTab == tabUsers)
				ListUsersDelete();
			else
				ListRolesDelete();
		}

		private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (tabControl.SelectedTab == tabUsers) {
				menuEditInsert.Text = "&Insert User...";
				menuEditDelete.Text = "&Delete User";
			} else {
				menuEditInsert.Text = "&Insert Role...";
				menuEditDelete.Text = "&Delete Role";
			}

		}

		private void menuHelpOnline_Click(object sender, EventArgs e)
		{
			System.Diagnostics.Process.Start("http://www.codeplex.com/AspUserManager");
		}

		private void menuHelpAbout_Click(object sender, EventArgs e)
		{
			AboutDialog dlg = new AboutDialog();
			dlg.ShowDialog(this);
		}

		private void menuFileExit_Click(object sender, EventArgs e)
		{
			Close();
		}

		//-------------------------------------------------------------------
		// Users Tab
 
		private void ListUsersInsert(object sender, EventArgs e)
		{
			EditUserDialog dlg = new EditUserDialog(null);
			if (dlg.ShowDialog(this) == DialogResult.OK) {
				ListUsersAdd(dlg.User);
			}
		}

		private void menuUsersEdit_Click(object sender, EventArgs e)
		{
			if (listUsers.FocusedItem == null) return;

			MembershipUser user = (MembershipUser)listUsers.FocusedItem.Tag;
			EditUserDialog dlg = new EditUserDialog(user);
			if (dlg.ShowDialog(this) == DialogResult.OK) {
				ListViewItem item = listUsers.FocusedItem;
				item.ImageIndex = GetUserIconIndex(user);
				item.SubItems[2].Text = user.Email;
				item.SubItems[3].Text = user.Comment;
				listUsers_SelectedIndexChanged(this, EventArgs.Empty);
			}
		}

		private void ListUsersRefresh(int selectIndex)
		{
			listUsers.Items.Clear();
			MembershipUserCollection users = Membership.GetAllUsers();
			foreach (MembershipUser user in users)
				ListUsersAdd(user);

			if (listUsers.Items.Count > selectIndex) {
				listUsers.Focus();
				listUsers.Items[selectIndex].Focused = true;
				listUsers.Items[selectIndex].Selected = true;
			}
		}

		private void ListUsersAdd(MembershipUser user)
		{
			ListViewItem item = new ListViewItem();
			item.ImageIndex = GetUserIconIndex(user);
			item.Tag = user;
			item.SubItems.Add(user.UserName);
			item.SubItems.Add(user.Email);
			item.SubItems.Add(user.Comment);
			listUsers.Items.Add(item);
		}

		private void ListUsersDelete()
		{
			if (listUsers.FocusedItem == null) return;

			MembershipUser user = (MembershipUser)listUsers.FocusedItem.Tag;
			if (MessageBox.Show("Would you like to delete user '" + user.UserName + "'?", 
				Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
				return;

			try {
				Membership.DeleteUser(user.UserName);
				listUsers.Items.Remove(listUsers.FocusedItem);
			} catch (Exception ex) {
				MessageBox.Show("The user could not be deleted.\n\n" + ex.Message);
			}
		}

		private static int GetUserIconIndex(MembershipUser user)
		{
			if (user.IsLockedOut)
				return 2;
			return 0;
		}

		private void listUsers_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (listUsers.FocusedItem == null) return;
			MembershipUser user = (MembershipUser)listUsers.FocusedItem.Tag;

			listUserRoles.Items.Clear();
			foreach (string role in Roles.GetRolesForUser(user.UserName))
				listUserRoles.Items.Add(role);
		}

		private void menuActionsUnlock_Click(object sender, EventArgs e)
		{
			if (listUsers.FocusedItem == null) return;
			MembershipUser user = (MembershipUser)listUsers.FocusedItem.Tag;
			user.UnlockUser();
			ListViewItem item = listUsers.FocusedItem;
			item.ImageIndex = GetUserIconIndex(user);
		}

		//-------------------------------------------------------------------
		// Roles Tab

		private void ListRolesInsert(object sender, EventArgs e)
		{
			EditRoleDialog dlg = new EditRoleDialog();
			if (dlg.ShowDialog(this) == DialogResult.OK) {
				listRoles.Items.Add(dlg.Role);
			}
		}

		private void ListRolesRefresh()
		{
			Cursor oldCursor = Cursor.Current;
			try {
				Cursor.Current = Cursors.WaitCursor;
				listRoles.Items.Clear();
				foreach (string role in Roles.GetAllRoles())
					listRoles.Items.Add(role);
			} finally {
				Cursor.Current = oldCursor;
			}
		}

		private void ListRolesDelete()
		{
			if (listRoles.SelectedItem == null) return;

			string role = (string)listRoles.SelectedItem;
			if (MessageBox.Show("Would you like to delete role '" + role + "'?",
				Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
				return;

			try {
				Roles.DeleteRole(role);

				int selected = listRoles.Items.IndexOf(role);
				listRoles.Items.Remove(role);

				// reselect
				if (selected >= listRoles.Items.Count)
					--selected;
				listRoles.SelectedIndex = selected;
			} catch (Exception ex) {
				MessageBox.Show("The role could not be deleted.\n\n" + ex.Message);
			}
		}

	}
}